package com.foxit.pdf2html5.web.foxitcloud.business;

import java.io.InputStreamReader;
import java.util.HashMap;

import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.log4j.Logger;

import com.foxit.pdf2html5.web.common.Config;
import com.foxit.pdf2html5.web.common.HttpConnectionManager;
import com.foxit.pdf2html5.web.foxitcloud.iterface.realization.FoxitCloudHttpKey;
import com.foxit.pdf2html5.web.foxitcloud.iterface.realization.FoxitCloudHttpState;
import com.foxit.pdf2html5.web.util.HashUtil;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;

public class FoxitCloudUploadFile {
	private static final Logger log =  Logger.getLogger(FoxitCloudUploadFile.class);
	
	private String rootPath = "/";
	
	public String getToken() {
		String tokens = null;
		JsonObject o = new JsonObject();
		String appId = Config.FOXIT_APP_ID_KEY;
		String userId = Config.FOXIT_USER_ID_KEY;
		o.addProperty(FoxitCloudHttpKey.APPID, appId);
		o.addProperty(FoxitCloudHttpKey.USERID, userId);
		String url = Config.FOXIT_URSER_TOKEN_URL_KEY;
		String result = sendPost(url,o);
		
		if(null != result){
			HashMap<String, Object> token = String2Map(result);
			tokens = (String)token.get(FoxitCloudHttpKey.TOKEN);
		}
		
		return tokens;
	}

	private String sendPost(String url, JsonObject jsonObject) {
		String readLine = "";
		HttpPost httpPost = null;
		HashMap<String, Object> map = new HashMap<String, Object>();
		try {
			HttpClient httpClient = (HttpClient) HttpConnectionManager.getHttpClient();
			httpPost = HttpConnectionManager.getHttpPost(url);
			httpPost.setEntity(new StringEntity(jsonObject.toString(), ContentType.APPLICATION_JSON));
			HttpResponse authResult = httpClient.execute(httpPost);
			int status = authResult.getStatusLine().getStatusCode();

			if (status == HttpStatus.SC_OK) {
				InputStreamReader reader = new InputStreamReader(authResult.getEntity().getContent());
				int flag;
				while((flag = reader.read()) != -1){
					readLine += (char)flag;
				}
				
				map = String2Map(readLine);
				Double ret =(Double)map.get(FoxitCloudHttpKey.RET);
				
				if(ret.intValue() != FoxitCloudHttpState.HTTP_SUCCESS){
					if(ret.intValue() != FoxitCloudHttpState.HTTP_SUCCESS_NOT_UPLOAD_BLOCKS){
						readLine = null;
						log.error("request url:" + url + " error, the error code:" + ret);
					}
				}
				
			}else{
				readLine = null;
				log.error("Http send Post error! url:" + url + " response status:" + status);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}finally{
			httpPost.releaseConnection();
		}
		return readLine;
	}

	public HashMap<String, Object> getBlockInfo(final String token,final String fileName,final byte[] fileData,String fileHash) {
		HashMap<String, Object> block = new HashMap<String, Object>();
		try{
		JsonObject o = new JsonObject();
		o.addProperty(FoxitCloudHttpKey.TOKEN, token);
		o.addProperty(FoxitCloudHttpKey.PATH, rootPath + fileName);
		o.addProperty(FoxitCloudHttpKey.DOCSIZE, fileData.length + "");
		o.addProperty(FoxitCloudHttpKey.DOCHASH, fileHash);
		o.addProperty(FoxitCloudHttpKey.DOCFILENAME, fileName);
		String url = Config.FOXIT_BLOCK_INFO_URL_KEY;
		String result = sendPost(url,o);
		
		if(null != result){//请求成功
			block = String2Map(result);
		}else{//错误 异常
			block = null;
		}
		
		}catch(Exception e){
			e.printStackTrace();
			return null;
		}
		
		return block;
	}
	
	@SuppressWarnings("unchecked")
	private HashMap<String,Object> String2Map(String str){
		Gson gson = new Gson();
		HashMap<String, Object> map = gson.fromJson(str, HashMap.class);
		
		return map;
	}
	
	@SuppressWarnings("unchecked")
	public HashMap<String, Object> uploadFileBlock(final String token,final String fileName,final byte[] fileData) {
		HashMap<String, Object> resmap = new HashMap<String, Object>();
		try{
			String fileHash = HashUtil.getMd5Sha1Hash(fileData);
			HashMap<String, Object> map = getBlockInfo(token,fileName,fileData,fileHash);
			
			if(map == null){
				log.error("get block info error!");
				return null;
			}
			
			String  docId = (String)map.get(FoxitCloudHttpKey.DOCID);
			HashMap<String, Object> blockInfo = (HashMap<String, Object>)map.get(FoxitCloudHttpKey.BLOCKINFO);
			String blockId = (String)blockInfo.get(FoxitCloudHttpKey.BLOCKID);
			Double blockSize = (Double)blockInfo.get(FoxitCloudHttpKey.BLOCKSIZE);
			JsonObject o = new JsonObject();
			o.addProperty(FoxitCloudHttpKey.TOKEN, token);
			o.addProperty(FoxitCloudHttpKey.DOCID, docId);
			o.addProperty(FoxitCloudHttpKey.PATH, rootPath + fileName);
			o.addProperty(FoxitCloudHttpKey.BLOCKID, blockId);
			o.addProperty(FoxitCloudHttpKey.BLOCKSIZE, blockSize.intValue());
			o.addProperty(FoxitCloudHttpKey.BLOCKHASH, fileHash);
			o.addProperty(FoxitCloudHttpKey.BLOCKDATA, Base64.encodeBase64String(fileData));
			
			String url = Config.FOXIT_BLOCK_UPLOAD_URL_KEY;
			String result = sendPost(url,o);
			
			if(null == result){//上传失败
				log.error("upload file block error!");
				return null;
			}else{
				resmap = String2Map(result);
			}
		}catch(Exception e){
			e.printStackTrace();
			return null;
		}
		
		return resmap;
	}
	
	
	public boolean delFile(final String token,final String fileName,String docId){
		boolean res = false;
		
		JsonObject o = new JsonObject();
		o.addProperty(FoxitCloudHttpKey.TOKEN, token);
		JsonObject ot = new JsonObject();
		ot.addProperty(FoxitCloudHttpKey.DOCID, docId);
		ot.addProperty(FoxitCloudHttpKey.PATH,rootPath + fileName);
		JsonArray array = new JsonArray();
		array.add(ot);
		o.add(FoxitCloudHttpKey.DOCLIST, array);
		
		String url = Config.FOXIT_CLOUND_DELETE_FILE_URL_KEY;
		String result = sendPost(url,o);
		
		if(null == result){//删除失败
			log.error("del file error!");
			res = false; 
		}else{
			res = true;
		}
		return res;
	}

}
